package com.bestcem.xm.common.core.sql.calculator;

import com.alibaba.fastjson.JSONObject;
import com.bestcem.xm.common.core.sql.ConditionConstant;
import com.bestcem.xm.common.core.sql.ConditionGrammarException;
import com.bestcem.xm.common.core.sql.ConditionProxy;
import com.bestcem.xm.common.core.sql.ParamsProxy;
import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.Map;

/**
 * @author ming.xue <ming.xue@idiaoyan.com>
 * @desc 简单条件解释器工厂
 * @date 2021-05-24
 *
 * <pre>
 *     支持的操作符: $eq、$ne、$in、$nin、$regex、$nregex、$range、$exists、$nexists
 *     支持的数据类型: string、number、datetime、select、level、address、tag、field_val_list
 * </pre>
 */
public class ConditionCalculatorFactory {
    /**
     * 创建新的解释器
     *
     *
     * @param groupMap
     * @param condition
     * @param params
     * @return
     */
    public static ConditionCalculator newCalculator(Map<String, List<String>> groupMap, JSONObject condition, JSONObject params) {
        if (condition == null || params == null) {
            throw new ConditionGrammarException("condition missing");
        }

        ConditionProxy conditionProxy = new ConditionProxy(condition);
        ParamsProxy paramsProxy = new ParamsProxy(params);
        // 初始化扩展字段参数
        paramsProxy.initExtendFieldParam(conditionProxy);

        String operator = StringUtils.trimToEmpty(conditionProxy.getOperator());
        switch (operator) {
            case ConditionConstant.Operators.GT:
                return new GtConditionCalculator(conditionProxy, paramsProxy);
            case ConditionConstant.Operators.GTE:
                return new GteConditionCalculator(conditionProxy, paramsProxy);
            case ConditionConstant.Operators.LT:
                return new LtConditionCalculator(conditionProxy, paramsProxy);
            case ConditionConstant.Operators.LTE:
                return new LteConditionCalculator(conditionProxy, paramsProxy);
            case ConditionConstant.Operators.EQ:
                return new EqConditionCalculator(conditionProxy, paramsProxy);
            case ConditionConstant.Operators.NE:
                return new NeConditionCalculator(conditionProxy, paramsProxy);
            case ConditionConstant.Operators.IN:
                return new InConditionCalculator(conditionProxy, paramsProxy);
            case ConditionConstant.Operators.REGEX:
                return new RegexConditionCalculator(conditionProxy, paramsProxy);
            case ConditionConstant.Operators.NIN:
                return new NinConditionCalculator(conditionProxy, paramsProxy);
            case ConditionConstant.Operators.NREGEX:
                return new NRegexConditionCalculator(conditionProxy, paramsProxy);
            case ConditionConstant.Operators.RANGE:
                return new RangeConditionCalculator(conditionProxy, paramsProxy);
            case ConditionConstant.Operators.EXISTS:
                return new ExistsConditionCalculator(conditionProxy, paramsProxy);
            case ConditionConstant.Operators.NEXISTS:
                return new NexistsConditionCalculator(conditionProxy, paramsProxy);
            default:
                String msg = String.format("condition.operator unsupported, operator: %s", operator);
                throw new ConditionGrammarException(msg);
        }
    }
}
